package main

import "fmt"

//定义管道channel
//var 变量名 chan 数据类型
//var intChan chan int    // int类型
//var mapChan chan map[int]string  // map[int]string 类型
//管道channel为引用类型，必须初始化才能写入数据，即make后才能使用

// 声明只读或只写管道
//var writeOnlyChan chan<- int
//var readOnlyChan <-chan int

func main() {
	intChan := make(chan int, 10) // 创建存放3个int类型的管道
	fmt.Println(intChan, &intChan)

	// 向管道写数据
	intChan <- 20
	num := 15
	intChan <- num
	intChan <- 45
	//intChan <- 10 // 管道容量为3，第四个数据无法写入
	// 管道数据，长度，容量
	fmt.Println(intChan, len(intChan), cap(intChan))

	// 从管道读取数据
	//var n1 int
	n1 := <-intChan
	fmt.Println(n1)
	fmt.Println(intChan, len(intChan), cap(intChan))

	//如果管道数据为空，再取则报告deadlock

	// 关闭管道
	//使用内置的close可以关闭管道
	//close(intChan)

	// 遍历管道
	intChan1 := make(chan int, 10)
	//for range管道遍历只能在管道关闭后才能正常遍历。
	//遍历时如果channel没有关闭，会出现deadlock错误
	//for循环遍历不需要关闭，并不会报错,但是不能使用，不能遍历所有数据
	for i := 0; i < 8; i++ {
		intChan1 <- i * i
	}
	close(intChan1)
	for v := range intChan1 {
		fmt.Println(v)
	}

	//普通for循环遍历，遍历得到的数据不完整
	//for i := 0; i < len(intChan1); i++ {
	//	num := <- intChan1
	//	fmt.Println(num)
	//}


	/*
	缓冲管道和非传冲管道
	缓冲通道就是指一个通道，带有一个缓冲区。发送到一个缓冲通道只有在缓冲区满时才被阻塞。
	类似地，从缓冲通道接收的信息只有在缓冲区为空时才会被阻塞
	*/
	//ch := make(chan type, capacity)
	//无缓冲通道的容量为0
	//具有缓冲区的管道容量大于0
}
